package common 
{
	import common.ITestResult;
	/**
	 * ...
	 * @author Luke Van In
	 */
	public class CompositeTestResult implements ICompositeTestResult
	{
		
		private var _description:String;
		
		private var _testResults:Vector.<ITestResult>;
		
		
		public function CompositeTestResult(description:String) 
		{
			this._description = description;
			
			this._testResults = new	Vector.<ITestResult>();
		}
		
		
		
		/**
		 * 
		 * @param	testResult
		 * @throws	Error	Test result must not be null
		 */
		public function addTestResult(testResult:ITestResult):void 
		{
			if (testResult == null)
				throw new Error("Cannot add null test result");
			
			this._testResults.push(testResult);
		}
		
		
		
		
		public function toString():String
		{
			var status:String = this.getStatus() ? "pass" : "fail";
			
			var message:String = this.getMessage();
			
			var s:String = this.getDescription() + " ->\n";
			
			if (this._testResults.length > 0)
			{
				var a:Vector.<String> = this.getTestResultsStrings();
				
				s += a.join("\n") + "\n";
			}
			else
			{
				s += "no tests\n";
			}
			
			s +=  this.getMessage();
			
			s += " (" + status + ")";
			
			s += "\n";
			
			return s;
		}
		
		
		
		
		private function getTestResultsStrings():Vector.<String>
		{
			var a:Vector.<String> = new Vector.<String>();
			
			for (var i:int = 0; i < this._testResults.length; i++)
				a.push(this.getDescription() + " -> " + this._testResults[i].toString());

			return a;
		}
		
		
		
		
		/**
		 * 
		 * @return
		 */
		public function getStatus():Boolean 
		{
			// check if one test has failed
			for (var i:int = 0; i < this._testResults.length; i++)
			{
				if (!this._testResults[i].getStatus())
					return false;
			}
			
			// all tests have passed
			return true; 
		}
		
		
		
		/**
		 * 
		 * @return
		 */
		public function getDescription():String
		{
			return this._description;
		}
		
		
		/**
		 * 
		 * @return
		 */
		public function getMessage():String 
		{
			// count total pass and fails
			var passCount:int = 0;
			
			var failCount:int = 0;
			
			for (var i:int = 0; i < this._testResults.length; i++)
			{
				if (this._testResults[i].getStatus())
					passCount ++;
				else
					failCount ++
			}
			
			
			var total:int = passCount + failCount; // yes we could just use this._testResults.length, but this looks less ambiguous
			
			
			var message:String = "pass:" + passCount + " fail:" + failCount + " (total:" + total + ")";
			
			return message;
		}
		
		
		
		private function createTestMessage(result:ITestResult):String
		{
			var message:String = result.getMessage();
			
			return message;
		}

		
	}

}